Now we're ready to
rotate the headlines, dates, and summaries. We'll define a function for
this task so that we can easily repeat the action each time we need it.
First, let's take care of updating the variables that are tracking which headline is active. The modulus operator (%) will let us easily cycle through the headline numbers. We can add 1 to the currentHeadline value each time our function is called, and then take this value modulus the headlineCount value to constrain the variable to valid headline numbers.
We should also update the oldHeadline value so that we can easily manipulate the headline that is moving out of view.
var headlineRotate = function() {
headline rotatorheadline rotate functioncurrentHeadline = (oldHeadline + 1) % headlineCount;
// Animate the headline positions here.
oldHeadline = currentHeadline;
};
Now we have to fill in the gap
with code that actually moves the headlines. First, we'll add an
animation that moves the old headline out of the way. Then, we'll
insert another animation that slides the new headline into view.
var headlineRotate = function() {
currentHeadline = (oldHeadline + 1) % headlineCount;
$('div.headline').eq(oldHeadline).animate(
{top: -hiddenPosition}, 'slow', function() {
$(this).css('top', hiddenPosition);
});
$('div.headline').eq(currentHeadline).animate(
{top: 0}, 'slow', function() {
pause = setTimeout(headlineRotate, 5000);
});
oldHeadline = currentHeadline;
};
In both cases, we're animating the top property of the news item. Recall that the items are hidden because they have a top value of hiddenPosition (which is a number greater than the height of the container). Animating this property to 0 brings an item into view; further animating it to -hiddenPosition moves it out of view again.
In both cases, we
also have a callback function specified to take action when the
animation is complete. When the old headline has completely slid out of
view, it gets its top property reset to hiddenPosition
so it is ready to return later. When the new headline is finished with
its animation, we want to queue up the next transition; this is done
with a call to the JavaScript setTimeout() function, which registers a function to be invoked after a specified period. In this case, we're causing to be fired again in five seconds (5000 milliseconds). headlineRotate()
We now have a cycle of
activity; once one animation completes, the next one is ready to
activate. It remains to call the function the first time; we'll do this
with another call to setTimeout(),
causing the first transition to happen 5 seconds after the RSS feed has
been retrieved. Now we have a functional headline rotator.
$(document).ready(function() {
$('#news-feed').each(function() {
var $container = $(this);
$container.empty();
$.get('news/feed.xml', function(data) {
$('rss item', data).each(function() {
var $link = $('<a></a>')
.attr('href', $('link', this).text())
.text($('title', this).text());
var $headline = $('<h4></h4>').append($link);
var pubDate = new Date($('pubDate', this).text());
var pubMonth = pubDate.getMonth() + 1;
var pubDay = pubDate.getDate();
var pubYear = pubDate.getFullYear();
var $publication = $('<div></div>')
.addClass('publication-date')
.text(pubMonth + '/' + pubDay + '/' + pubYear);
var $summary = $('<div></div>')
.addClass('summary')
.html($('description', this).text());
$('<div></div>')
.addClass('headline')
.append($headline, $publication, $summary)
.appendTo($container);
});
var currentHeadline = 0, oldHeadline = 0;
var hiddenPosition = $container.height() + 10;
$('div.headline').eq(currentHeadline).css('top', 0);
var headlineCount = $('div.headline').length;
var pause;
var headlineRotate = function() {
currentHeadline = (oldHeadline + 1) % headlineCount;
$('div.headline').eq(oldHeadline).animate(
{top: -hiddenPosition}, 'slow', function() {
$(this).css('top', hiddenPosition);
});
$('div.headline').eq(currentHeadline).animate(
{top: 0}, 'slow', function() {
pause = setTimeout(headlineRotate, 5000);
});
oldHeadline = currentHeadline;
};
pause = setTimeout(headlineRotate, 5000);
});
});
});
Partially through
the animation, we can see one headline cropped at the top, and the next
coming into view cropped at the bottom: